package com.pi.wms.service;

import com.alibaba.fastjson.JSONArray;
import com.pi.common.CodesConstants;
import com.pi.common.utils.StringUtils;
import com.pi.core.service.UserAccessUtils;
import com.pi.framework.core.repository.IBaseRepository;
import com.pi.framework.core.service.impl.BaseCrudService;
import com.pi.framework.core.util.ConvertUtils;
import com.pi.framework.core.util.DateUtils;
import com.pi.framework.core.util.SecurityUtils;
import com.pi.framework.core.util.csv.CsvExporter;
import com.pi.framework.web.util.CsvView;
import com.pi.sys.service.UserDivisionService;
import com.pi.wms.common.WmsConstants;
import com.pi.wms.common.WmsTextUtils;
import com.pi.wms.entity.TwtActTransList;
import com.pi.wms.entity.VwtActChangeTransList;
import com.pi.wms.entity.VwtActShipTransList;
import com.pi.wms.fac.LocationResolver;
import com.pi.wms.repository.ChangeTransRepository;
import com.pi.wms.repository.ShipTransRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.datatables.mapping.DataTablesInput;
import org.springframework.data.jpa.datatables.mapping.DataTablesOutput;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;


@Slf4j
@Service
public class ChangeTransService extends BaseCrudService<VwtActChangeTransList, Long>{

	@Autowired
	protected ChangeTransRepository repository;

    @Autowired
    protected LocationResolver locationResolver;

    @Autowired
    protected UserDivisionService userDivisionService;



	@Override
	protected IBaseRepository<VwtActChangeTransList,Long> getRepository() {
		return this.repository;
	}


	@Override
	protected Predicate toPredicate(Root<VwtActChangeTransList> root, CriteriaQuery<?> cq, CriteriaBuilder cb, Map<String, ?> query) {
		List<Predicate> list = new ArrayList<Predicate>();

		Boolean enabled = ConvertUtils.convertObjectToBoolean(query.get("enabled"));
		if (enabled) {
			list.add(cb.equal(root.get("enabled"), enabled));
		}
		// q for select2 searching
		String q = (String) query.get("q");
        if (!StringUtils.isNullOrBlank(q)) {
			list.add(cb.or(cb.like(root.get("no"), "%" + q + "%"), cb.like(root.get("name"), "%" + q + "%")));
		}

		// no searching
		String number = (String) query.get("number");
        if (!StringUtils.isNullOrBlank(number)) {
			list.add(cb.like(root.get("number"), "%" + number + "%"));
		}
		String type = (String) query.get("type");
        if (!StringUtils.isNullOrBlank(type)) {
			list.add(cb.equal(root.get("type"), type));
		}
		String docnum = (String) query.get("docnum");
        if (!StringUtils.isNullOrBlank(docnum)) {
			list.add(cb.like(root.get("docNumber"), "%" + docnum + "%"));
		}
        String category = (String) query.get("category");
        if (!StringUtils.isNullOrBlank(category)) {
            list.add(cb.equal(root.get("category"), category.trim()));
        }

		String material = (String) query.get("material");
		if (!StringUtils.isNullOrBlank(material)) {
			list.add(cb.or(cb.like(root.get("materialCode"), "%" + material + "%"), cb.like(root.get("materialName"), "%" + material + "%")));
		}

        String lotattr06 = (String) query.get("lotattr06");
        if (!StringUtils.isNullOrBlank(lotattr06)) {
            list.add(cb.like(root.get("fromLotattr06"), "%" + lotattr06 + "%"));
        }

        String lotattr07 = (String) query.get("lotattr07");
        if (!StringUtils.isNullOrBlank(lotattr07)) {
            list.add(cb.like(root.get("fromLotattr07"), "%" + lotattr07 + "%"));
        }
        String contnum = (String) query.get("containnum");
        if (!StringUtils.isNullOrBlank(contnum)) {
            //list.add(cb.like(root.get("fromContainNumber"), "%" + contnum + "%"));
            list.add(cb.or(cb.like(root.get("fromContainNumber"), "%" + contnum + "%"), cb.like(root.get("toContainNumber"), "%" + contnum + "%")));
        }
        String tracenum = (String) query.get("tracenum");
        if (!StringUtils.isNullOrBlank(tracenum)) {
            list.add(cb.or(cb.like(root.get("fromTraceNumber"), "%" + tracenum + "%"), cb.like(root.get("toTraceNumber"), "%" + tracenum + "%")));
        }
        String createdby = (String) query.get("createdby");
        if (!StringUtils.isNullOrBlank(createdby)) {
            list.add(cb.equal(root.get("createdBy"), createdby.trim()));
        }

        String fromtime = (String) query.get("fromopentime");
        if (!StringUtils.isNullOrBlank(fromtime)) {
            //Date ftime= DateUtils.parse(fromtime, DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS);
            Date ftime= DateUtils.tryParse(fromtime);
            if (ftime!=null){
                list.add(cb.greaterThanOrEqualTo(root.get("openTime"), ftime));
            }
        }
        String totime = (String) query.get("toopentime");
        if (!StringUtils.isNullOrBlank(totime)) {
            //Date ttime= DateUtils.parse(totime, DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS);
            Date ttime= DateUtils.tryParse(totime);
            if (ttime!=null){
                list.add(cb.lessThanOrEqualTo(root.get("openTime"), ttime));
            }
        }

        fromtime = (String) query.get("fromclosetime");
        if (!StringUtils.isNullOrBlank(fromtime)) {
            //Date ftime= DateUtils.parse(fromtime, DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS);
            Date ftime= DateUtils.tryParse(fromtime);
            if (ftime!=null){
                list.add(cb.greaterThanOrEqualTo(root.get("closeTime"), ftime));
            }
        }
        totime = (String) query.get("toclosetime");
        if (!StringUtils.isNullOrBlank(totime)) {
            //Date ttime= DateUtils.parse(totime, DateUtils.FORMAT_DATE_YYYY_MM_DD_HH_MM_SS);
            Date ttime= DateUtils.tryParse(totime);
            if (ttime!=null){
                list.add(cb.lessThanOrEqualTo(root.get("closeTime"), ttime));
            }
        }
        //
        Date date=null;
        String fromdate = (String) query.get("fromcreatedate");
        if (!StringUtils.isNullOrBlank(fromdate)) {
            date = WmsTextUtils.plainDate(fromdate,true);
            if (date!=null){
                list.add(cb.greaterThanOrEqualTo(root.get("createdDate"), date));
            }
        }
        String todate = (String) query.get("tocreatedate");
        if (!StringUtils.isNullOrBlank(todate)) {
            date = WmsTextUtils.plainDate(todate,false);
            if (date!=null){
                list.add(cb.lessThanOrEqualTo(root.get("createdDate"), date));
            }
        }
        //
        String[] types = ConvertUtils.convertToStringArray(query.get("types"));
        List<String> indoctypes=null;
        if (types != null) {
            indoctypes = Arrays.asList(types);
            if (indoctypes != null && indoctypes.size() > 0) {
                Predicate p = root.get("type").in(indoctypes);
                list.add(cb.and(p));
            }
        }

        //页面选择
        Long divisionid= UserAccessUtils.getCurrentDivision();
        if ((divisionid!=null) && (divisionid>0L)){
            list.add(cb.equal(root.get("divisionId"), divisionid));
        }
        //权限控制
        List<Long> userDivisionIds = this.userDivisionService.findIdsByUsersId(SecurityUtils.getLoginUserId());
        if ((userDivisionIds!=null)&&(userDivisionIds.size()>0)){
            Predicate p = root.get("divisionId").in(userDivisionIds);
            list.add(cb.and(p));
        }

        String option=CodesConstants.COMMON_FLAG_NO;
        if (query.get(WmsConstants.ACT_QUERY_OPTION)!=null){
            option=(String)query.get(WmsConstants.DOCUMENT_QUERY_OPTION);
            option=option.trim();
        }
        if (!option.equalsIgnoreCase(WmsConstants.ACT_QUERY_OPTION_LISTALL)){
            list.add(cb.notEqual(root.get("transStatus"), CodesConstants.COMMON_STATUS_CANCELLED));
        }

		Long[] array = ConvertUtils.convertToLongArray(query.get("excludeIds"));
		if (array != null) {
			List<Long> ids = Arrays.asList(array);
			if (ids != null && ids.size() > 0) {
				if (ids.size() >= 1000) {
					ids = ids.subList(0, 1000);
				}
				Predicate p = root.in(ids);
				list.add(cb.and(cb.not(p)));
			}
		}
		Predicate[] p = new Predicate[list.size()];
		return cb.and(list.toArray(p));
	}


}
